﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.serverpackets;
using l1cs.server.datatables;
using l1cs.server.templates;
using l1cs.server.model;

namespace l1cs.server.clientpackets
{
    public class C_Mail : ClientBasePacket
    {
        private const String _C_MAIL = "[C] C_Mail";

        private static Logger _log = Logger.getLogger( typeof( C_Mail ).FullName );

        private static int TYPE_NORMAL_MAIL = 0; // 一般
        private static int TYPE_CLAN_MAIL = 1; // 血盟
        private static int TYPE_MAIL_BOX = 2; // 保管箱

        public C_Mail( byte[] abyte0, ClientThread client )
            : base( abyte0 )
        {
            int type = readC();
            L1PcInstance pc = client.getActiveChar();

            if ( type == 0x00 || type == 0x01 || type == 0x02 )
            { // 開く
                pc.sendPackets( new S_Mail( pc.getName(), type ) );
            }
            else if ( type == 0x10 || type == 0x11 || type == 0x12 )
            { // 読む
                int mailId = readD();
                L1Mail mail = MailTable.getMail( mailId );
                if ( mail.getReadStatus() == 0 )
                {
                    MailTable.getInstance().setReadStatus( mailId );
                }
                pc.sendPackets( new S_Mail( mailId, type ) );
            }
            else if ( type == 0x20 )
            { // 一般メールを書く
                int unknow = readH();
                String receiverName = readS();
                byte[] text = readByte();
                L1PcInstance receiver = L1World.getInstance().
                        getPlayer( receiverName );
                if ( receiver != null )
                { // オンライン中
                    if ( getMailSizeByReceiver( receiverName,
                            TYPE_NORMAL_MAIL ) >= 20 )
                    {
                        pc.sendPackets( new S_Mail( type ) );
                        return;
                    }
                    MailTable.getInstance().writeMail( TYPE_NORMAL_MAIL,
                            receiverName, pc, text );
                    if ( receiver.getOnlineStatus() == 1 )
                    {
                        receiver.sendPackets( new S_Mail( receiverName,
                                TYPE_NORMAL_MAIL ) );
                    }
                }
                else
                { // オフライン中
                    L1PcInstance restorePc = CharacterTable.getInstance()
                            .restoreCharacter( receiverName );
                    if ( restorePc != null )
                    {
                        if ( getMailSizeByReceiver( receiverName,
                                TYPE_NORMAL_MAIL ) >= 20 )
                        {
                            pc.sendPackets( new S_Mail( type ) );
                            return;
                        }
                        MailTable.getInstance().writeMail( TYPE_NORMAL_MAIL,
                                receiverName, pc, text );
                    }
                    else
                    {
                        pc.sendPackets( new S_ServerMessage( 109, receiverName ) ); // %0という名前の人はいません。
                    }
                }
            }
            else if ( type == 0x21 )
            { // 血盟メールを書く
                int unknow = readH();
                String clanName = readS();
                byte[] text = readByte();
                L1Clan clan = L1World.getInstance().getClan( clanName );
                if ( clan != null )
                {
                    foreach ( String name in clan.getAllMembers() )
                    {
                        int size = getMailSizeByReceiver( name, TYPE_CLAN_MAIL );
                        if ( size >= 50 )
                        {
                            continue;
                        }
                        MailTable.getInstance().writeMail( TYPE_CLAN_MAIL, name,
                                pc, text );
                        L1PcInstance clanPc = L1World.getInstance().
                                getPlayer( name );
                        if ( clanPc != null )
                        { // オンライン中
                            clanPc.sendPackets( new S_Mail( name,
                                    TYPE_CLAN_MAIL ) );
                        }
                    }
                }
            }
            else if ( type == 0x30 || type == 0x31 || type == 0x32 )
            { // 削除
                int mailId = readD();
                MailTable.getInstance().deleteMail( mailId );
                pc.sendPackets( new S_Mail( mailId, type ) );
            }
            else if ( type == 0x40 )
            { // 保管箱に保存
                int mailId = readD();
                MailTable.getInstance().setMailType( mailId, TYPE_MAIL_BOX );
                pc.sendPackets( new S_Mail( mailId, type ) );
            }
        }

        private int getMailSizeByReceiver( String receiverName, int type )
        {
            List<L1Mail> mails = new List<L1Mail>();
            foreach ( L1Mail mail in MailTable.getAllMail() )
            {
                if ( string.Compare( mail.getReceiverName(), receiverName, true ) == 0 )
                {
                    if ( mail.getType() == type )
                    {
                        mails.Add( mail );
                    }
                }
            }
            return mails.Count;
        }

        override
        public String getType()
        {
            return _C_MAIL;
        }
    }
}